module NlGasStations

  class Parser

    attr_reader :results

    def initialize(html)
      @heading = []
      element = 'form+ table'
      @table = html.at_css(element)
    end

    ##
    # Parse all rows of the html table.
    def parse
      results = []
      @table.css('tr').each_with_index do |row, row_index|
        if row_index == 0
          parse_heading(row)
        else
          results << parse_row(row)
        end
      end
      @results = format_results(results)
    end

    private

    ##
    # Parse the heading row of the html table.
    def parse_heading(row)
      row.css('td').each_with_index do |col, col_index|
        if col_index > 0
          @heading << col.at_css('b').text.downcase
        end
      end
    end

    ##
    # Parse a row of the html table.
    def parse_row(row)
      row_data = {}
      row.css('td').each_with_index do |col, col_index|
        row_data[@heading[col_index]] = col.text
      end
      row_data
    end

    ##
    # Format the results.
    def format_results(results)
      formatted_results = []
      results.each do |row|
        row_data = {}
        row.each do |col, value|
          if col == @heading[0]
            row_data[:gas_station] = parse_address_column(value)
          elsif col == @heading[1]
            row_data[:fuel_type] = value.downcase.gsub(/\s/, '_').to_sym
          elsif col == @heading[2]
            row_data[:price] = parse_price_column(value)
          elsif col == @heading[3]
            row_data[:date] = parse_date_column(value)
          end
        end
        formatted_results << row_data
      end
      formatted_results
    end

    ##
    # Parse the Gas Station column into: name, street_address, postal_code and city
    def parse_address_column(value)
      result = {}
      lines = value.lines.map(&:chomp)
      result[:name] = lines[1].strip
      result[:street_address] = lines[2].strip
      place = lines[3].strip.split(/\s+/)
      result[:postal_code] = place[0]
      result[:city] = place[1]
      result
    end

    ##
    # Parse the price column. Remove the euro sign and return as a float.
    def parse_price_column(value)
      splitted = value.gsub(',', '.').split(/\s+/)
      splitted[1].to_f
    end

    ##
    # Parse the date column.
    # Month names are translated from dutch to english, then a Date object is created and returned.
    def parse_date_column(value)
      translation = {'januari' => 1, 'februari' => 2, 'maart' => 3, 'april' => 4, 'mei' => 5, 'juni' => 6, 'july' => 7, 'augustus' => 8,
                     'september' => 9, 'oktober' => 10, 'november' => 11, 'december' => 12}
      splitted = value.split(/\s+/)
      day = splitted[0].to_i
      month = translation[splitted[1].downcase]
      year = splitted[2].to_i
      Date.new(year, month, day)
    end

  end
end